package prjtgl.metier;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
import prjtgl.bdd.comptes.HMembre;
import prjtgl.bdd.comptes.HRecruteur;
import prjtgl.bdd.comptes.HUtilisateur;
import prjtgl.bdd.comptes.interactions_utilisateur.HSignalement;
import prjtgl.bdd.comptes.profil_societe.HSociete;
import prjtgl.bdd.comptes.profil_utilisateur.HDomaineExpertise;
import prjtgl.bdd.comptes.profil_utilisateur.HProfil;
import prjtgl.bdd.comptes.profil_utilisateur.poste.HExperience;
import prjtgl.bdd.comptes.profil_utilisateur.poste.HPoste;
import prjtgl.bdd.paiement.HPorteMonnaie;
import prjtgl.metier.comptes.Membre;
import prjtgl.metier.comptes.Recruteur;
import prjtgl.metier.comptes.Utilisateur;
import prjtgl.metier.comptes.interactions_utilisateur.Signalement;
import prjtgl.metier.comptes.profil_societe.Societe;
import prjtgl.metier.comptes.profil_utilisateur.DomaineExpertise;
import prjtgl.metier.comptes.profil_utilisateur.Profil;
import prjtgl.metier.comptes.profil_utilisateur.poste.Direction;
import prjtgl.metier.comptes.profil_utilisateur.poste.Experience;
import prjtgl.metier.comptes.profil_utilisateur.poste.Poste;
import prjtgl.metier.paiement.Paiement;
import prjtgl.metier.paiement.PorteMonnaie;


/**
 * Application
 * @author Lucie
 */
public class Application {
    
    
   
    
    /**
     * Singleton to get Application
     */
        private static class ApplicationHolder {
            private final static Application instance_ = new Application();
        }

    /**
     * Get the instance of the Sigleton ApplicationHandler
     *
     * @return ApplicationHandler - the single ApplicationHandler instance
     */
    public static Application getInstance() {
        return ApplicationHolder.instance_;
    }  
    
    
	/**
	 * Obtenir la liste des signalements
	 * @return Liste des signalements
	 */
	public ArrayList<Signalement> listerSignalements(){
		HSignalement hs = new HSignalement();
		return (ArrayList<Signalement>) hs.listerTout();
	}
	/**
	 * Obtenir la liste des membres
	 * @return Liste des membres
	 */
	public ArrayList<Membre> listerMembres(){
		// TODO
		throw new UnsupportedOperationException("Not supported yet.");
	}
	/**
	 * Obtenir la liste des profils
	 * @return Liste des profils
	 */
	public ArrayList<Profil> listerProfils(){
		// TODO
		throw new UnsupportedOperationException("Not supported yet.");
	}
	/**
	 * Obtenir la liste des domaines d'expertise
	 * @return Liste des domaines d'expertise
	 */
	public ArrayList<DomaineExpertise> listerDomainesExpertise(){
		HDomaineExpertise hd = new HDomaineExpertise();
		return (ArrayList<DomaineExpertise>) hd.listerTout();
	}
	
	/**
	 * Obtenir la liste des recruteurs
	 * @return Liste des recruteurs
	 */
	public List<Recruteur> listerRecruteurs(){
            HRecruteur hr=new HRecruteur();
		return  hr.listerTout();
	}
	
	/**
	 * Obtenir la liste des postes
	 * @return Liste des postes
	 */
	public ArrayList<Poste> listerPostes(){
		HPoste p = new HPoste();
		return (ArrayList<Poste>) p.listerTout();
	}
	
	/**
	 * Obtenir la liste des societes
	 * @return Liste des societes
	 */
	public ArrayList<Societe> listerSocietes(){
		HSociete p = new HSociete();
		return (ArrayList<Societe>) p.listerTout();
	}
	
	/**
	 * Valide un recruteur donne
	 * @param r Recruteur a valider
	 */
	public void validerRecruteur(Recruteur r){
		r.setConfirme(true);
                updateRecruteur(r);
	}
	
	/**
	 * Modifie un domaine d'expertise
	 * @param intitule Intitule actuel du domaine
	 * @param nouvelIntitule Nouvel intitule
	 */
	public void editerDomaineExpertise(String intitule, String nouvelIntitule){
		this.rechercherDomainesExpertise(intitule).setIntitule(nouvelIntitule);
                this.rechercherDomainesExpertise(nouvelIntitule).update();
	}
	
	/**
	 * Ajouter un nouveau domaine d'expertise
	 * @param intitule Intitule du domaine d'expertise
	 * @return Domaine d'expertise cree
	 */
	public DomaineExpertise ajouterDomaineExpertise(String intitule){
                if(Application.getInstance().rechercherDomainesExpertise(intitule)!=null){ return null;}
                DomaineExpertise d = new DomaineExpertise();
                HDomaineExpertise hd = new HDomaineExpertise();
                d.setIntitule(intitule);
                hd.enregistrer(d);
                return d;
	}
	
	/**
	 * Ajoute un nouveau poste
	 * @param intitule Intitule du nouveau poste
	 * @return Poste cree
	 */
	public Poste ajouterPoste(String intitule){
            
		// TODO
		throw new UnsupportedOperationException("Not supported yet.");
	}
	
	/**
	 * Ajoute une nouvelle societe
	 * @param nomSociete Nom de la societe
	 * @return Societe cree
	 */
	public Societe ajouterSociete(String nomSociete){
		HSociete hsociete = new HSociete();
                
                Societe societe = new Societe();
                societe.setNom(nomSociete);
                hsociete.enregistrer(societe);
                
                return societe;
                
	}
	
	/**
	 * Supprime un domaine d'expertise donne
	 * @param intitule Intitule du domaine d'expertise a supprimer
	 */
	public void supprimerDomaineExpertise(String intitule){
		// TODO
		throw new UnsupportedOperationException("Not supported yet.");
	}
	
	/**
	 * Supprime un utilisateur de l'application
	 * @param email Email de l'utilisateur a supprimer
	 */
	public void supprimerUtilisateur(String email){
		// TODO
		throw new UnsupportedOperationException("Not supported yet.");
	}
	
	/**
	 * Retourne la societe recherchee
	 * @param nomSociete Nom de la societe recherchee
	 * @return Societe trouvee
	 */
	public Societe rechercherSociete(String nomSociete){
		// TODO
		HSociete hsociete = new HSociete();
                return hsociete.getSociete(nomSociete);
	}
	
	/**
	 * Retourne la direction recherchee
	 * @param intitule Intitule de la direction recherchee
	 * @return Direction trouvee
	 */
	public Direction rechercherDirection(String description){
		// TODO
		throw new UnsupportedOperationException("Not supported yet.");
	}
	
	/**
	 * Retourne le profil recherche
	 * @param intitule Intitule du profil recherche
	 * @return Profil trouve
	 */
	public Profil rechercherProfil(String intitule)
        {
                HProfil hp = new HProfil();
                return hp.rechercherProfilParIntitule(intitule);
	}
	
	/**
	 * Retourne le domaine d'expertise recherche
	 * @param intitule Intitule du domaine d'expertise recherche
	 * @return Domaine d'expertise trouve
	 */
	public DomaineExpertise rechercherDomainesExpertise(String intitule)
        {
                HDomaineExpertise hd = new HDomaineExpertise();
                return hd.rechercherParIntitule(intitule);
	}
	
	/**
	 * Retourne le poste recherche
	 * @param intitule Intitule du poste recherche
	 * @return Poste trouve
	 */
	public Poste rechercherPoste(String intitule){
		// TODO
		throw new UnsupportedOperationException("Not supported yet.");
	}
	
	/**
	 * Retourne le ou les membres recherches
	 * @param nom Nom du membre recherche
	 * @param prenom Prenom du membre recherche
	 * @param societe Societe du membre recherche
         * @param email Email du membre recherche
	 * @return Membre(s) qui correspondent aux criteres de recherche
	 */
	public List<Membre> rechercherMembre(String nom, String prenom, String email, String societe)
        {
            HMembre hm = new HMembre();
            return hm.rechercherMembreMultiCrit(email, nom, prenom, societe);
	}
	
	/**
	 * Renvoie un utilisateur recherche
	 * @param email Email de l'utilisateur
	 * @return Utilisateur qui correspond a la recherche
	 */
	public Utilisateur rechercherUtilisateur(String email){
		HUtilisateur hu = new HUtilisateur();
		return hu.rechercherUtilisateurParEmail(email);
	}
	
	/**
	 * Creer un nouveau membre dans l'application
	 * @param email Email du membre
	 * @param motDePasse Mot de passe du membre
	 * @param nom Nom du membre
	 * @param prenom Prenom du membre
	 * @return VRAI si le membre a ete cree, FAUX sinon
	 */
	public boolean creerMembre(Membre membre)
        {
            HMembre hm = new HMembre();
      
            hm.enregistrer(membre);
            return true;
	}
	
        /**
	 * Update un membre dans l'application
	 * @param membre Membre
	 * @return VRAI si le membre a ete cree, FAUX sinon
	 */
        public boolean updateMembre(Membre membre)
        {
            HMembre hm = new HMembre();
            hm.enregistrer(membre);
            return true;
        }
        
	/**
	 * Creer un nouveau recruteur dans l'application
	 * @param email Email du recruteur
	 * @param motDePasse Mot de passe du recruteur
	 * @param nomSociete Nom de la societe du recruteur
	 * @return VRAI si le recruteur a ete cree, FAUX sinon
	 */
	public boolean creerRecruteur(String email, String motDePasse, String nomSociete){
                HRecruteur hr = new HRecruteur();
                Recruteur r = new Recruteur();
                r.setRole("recruteur");
                r.setConfirme(false);
                r.setEmail(email);
                r.setMotDePasse(motDePasse);
                Societe societe = this.rechercherSociete(nomSociete);
                if(societe==null){
                    HSociete hsociete = new HSociete();
                    societe = new Societe();
                    societe.setNom(nomSociete);
                    hsociete.enregistrer(societe);
                    
                }
                r.setSociete(societe);
                
                
                
                r.setDescription("");
                
                
                hr.enregistrer(r);
		return true;
	}
        
        
        
        public boolean updateRecruteur(Recruteur r){
            HRecruteur hr = new HRecruteur();
            hr.enregistrer(r);
            return true;
        }
	
	/**
	 * Recherche le profil d'un membre donne
	 * @param email email du membre recherché
	 */
	public Membre rechercherMembre(String email){
		HMembre hm = new HMembre();
		return hm.rechercherMembreParEmail(email);
	}
	
        
        public boolean creerExperience(Experience e)
        {
            HExperience he = new HExperience();
            he.enregistrer(e);
            return true;
        }
        
        public boolean updateExperience(Experience e)
        {
            HExperience he = new HExperience();
            he.enregistrer(e);
            return true;
        }
        
	/**
	 * Rechercher une ressource dans l'application
	 * @param lstDomaines Liste des domaines necessaires
	 * @param profil Profil recherche
	 * @param experienceMin Nombre d'annees minimum d'experience n�cessaire
	 * @param dateDispo Date a laquelle le membre doit etre disponible
	 * @return Membres qui correspondent aux criteres de recherche
	 */
	public Map<Membre, Integer> rechercherRessource(ArrayList<DomaineExpertise> lstDomaines, Profil profil, Integer experienceMin, Date dateDispo){
		HRecruteur hr = new HRecruteur();
		return hr.rechercheRessource(lstDomaines, profil == null ? null : profil.getIntitule(), experienceMin, dateDispo);
	}
	
	/**
	 * Retourne la liste des domaines d'expertise presents dans l'application
	 * @return Liste des domaines
	 */
	public List<DomaineExpertise> getDomainesExpertise(){
		HDomaineExpertise h = new HDomaineExpertise();
		return h.listerTout();
	}
}
